home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / fixes.arc / MEMCPY.S < prev    next >
Text File  |  1985-11-20  |  2KB  |  53 lines

  1. * memcpy by David Brooks  1/23/89
  2. *        changed to move in 8-byte blocks and shortened slightly
  3. *     by Dale Schumacher and John Stanley  3/18/89
  4. *
  5. *    char *memcpy(dest, source, len)
  6. *        char *dest        at 4(sp)
  7. *        char *source        at 8(sp)
  8. *        unsigned int len    at 12(sp)
  9. *
  10. * This is generally optimized around the commonest case (even alignment,
  11. * more than 8 bytes) but the time savings and space cost are minimal.
  12. * Also, we avoid using "btst #n,dn" because of a bug in the Sozobon
  13. * assembler.
  14.  
  15. .text
  16. .globl _memcpy
  17. _memcpy:
  18.     lea    12(a7),a2    ; Point to argument list
  19.     move.w    (a2),d2        ; d2 = len
  20.     move.l    -(a2),a0    ; a0 = source
  21.     move.l    -(a2),a1    ; a1 = dest
  22.     move.l    a1,d0        ; d0 = dest, ready to return
  23.  
  24.     move.l    a0,d1        ; Check for odd/even alignment
  25.     add.w    a1,d1        ; This is really eor.w on the lsb.  Really.
  26.     asr.w    #1,d1        ; Get lsb into C.  If it's 1, alignment is off.
  27.     bcs    memcpy5        ; Go do it slowly
  28.  
  29.     move.l    a0,d1        ; Check for initial odd byte
  30.     asr.w    #1,d1        ; Get lsb
  31.     bcc    memcpy1
  32.     subq.w    #1,d2        ; Move initial byte
  33.     bcs    memcpy6        ;  (unless d2 was 0).  We could use dbra here,
  34.     move.b    (a0)+,(a1)+    ;   but that would have been bigger.
  35. memcpy1:
  36.     moveq.l    #7,d1        ; Split into a 8-byte block count and remainder
  37.     and.w    d2,d1
  38.     lsr.w    #3,d2
  39.     bra    memcpy3        ; Enter loop.  Note d2 could equal 0.
  40. memcpy2:
  41.     move.l    (a0)+,(a1)+
  42.     move.l    (a0)+,(a1)+
  43. memcpy3:
  44.     dbra    d2,memcpy2
  45.     move.w    d1,d2        ; Move remainder count to loop control
  46.     bra    memcpy5        ; Enter final loop.  Again d2 could equal 0.
  47. memcpy4:
  48.     move.b    (a0)+,(a1)+    ; Handle the odd/even aligned case
  49. memcpy5:
  50.     dbra    d2,memcpy4
  51. memcpy6:
  52.     rts            ; All done.
  53.